const lodash = require(`lodash`)
const pointsFlow = require(`./points-flow`)
const packages = require(`./packages`)
const store = require(`./store`)
const goods = require(`./goods`)
const levelBenefits = require(`./level-benefits`)
const member = require(`./member`)
const rechargeCards = require(`./rechargeCards`)
const addresses = require(`./addresses`)
const attendance = require(`./attendance`)
const customPoints = require(`./custom-points`)
const pointsMall = require(`./points-mall`)
const attendanceList = require(`./attendance-list`)
const todayAttendance = require(`./today-attendance`)
const orders = require(`./orders`)
const customerCoupons = require(`./customer-coupons`)
const giftCards = require(`./gift-cards`)

const { wrapApiData } = require(`../util.js`)

/** @type {import('mockm/@types/config').Config} */
module.exports = (util) => {
  const {
    libObj: { mockjs },
    toolObj,
  } = util
  return {
    api: {
      async 'post /login'(req, res, next) {
        const { user, pass } = req.body
        const db = await getDb()
        const findUser = db.chain.get(`user`).find({ user, pass }).value()
        if (findUser) {
          res.json(findUser)
        } else {
          res.status(403).json({ msg: `用户名或密码错误` })
        }
      },
      async 'post /customer_orders'(req, res, next) {
        const db = await getDb()
        const orders = req.body
        // 创建时间
        orders.created_at = Number(mockjs.mock(`@now(T)`)) / 1000
        // 取单号
        orders.sort_num = Number(mockjs.mock(`@now(HHmmss)`))
        // 订单号
        orders.order_no =
          Number(mockjs.mock(`@now(T)`)) + mockjs.mock(/\d\d\d\d/)
        next()
        const findRes = db.chain
          .get(`store`)
          .find({ id: orders.storeId })
          .value()
        res.mm.resHandleJsonApi = (arg) => {
          // 查询商店详情
          arg.data.store = findRes
          return arg.resHandleJsonApi(arg)
        }
      },
      async 'patch /customer_orders/:id'(req, res, next) {
        const db = await getDb()
        const orders = req.body
        if (orders.status > 2) {
          // 完成制作时间
          orders.productioned_time =
            orders.productioned_time || mockjs.mock(`@now(yyyy-MM-dd HH:mm:ss)`)
        }
        if (orders.status === 4) {
          // 完成时间
          orders.completed_time =
            orders.completed_time || mockjs.mock(`@now(yyyy-MM-dd HH:mm:ss)`)
        }
        next()
        const findRes = db.chain
          .get(`store`)
          .find({ id: orders.storeId })
          .value()
        res.mm.resHandleJsonApi = (arg) => {
          // 查询商店详情
          arg.data.store = findRes
          return arg.resHandleJsonApi(arg)
        }
      },
      async 'get /customer_orders/:id'(req, res, next) {
        const db = await getDb()
        next()
        res.mm.resHandleJsonApi = (arg) => {
          arg.data.status_text = {
            1: `已下单`,
            2: `制作中`,
            3: `配送中`,
            4: `已完成`,
          }[arg.data.status]
          arg.data.store = db.chain
            .get(`store`)
            .find({ id: arg.data.storeId })
            .value()
          return arg.resHandleJsonApi(arg)
        }
      },
      async 'get /store/:id'(req, res, next) {
        next()
        res.mm.resHandleJsonApi = (arg) => {
          // 商店距离当前用户多少米
          arg.data.distance_text = mockjs.mock(`@int(111,999)m`)
          return arg.resHandleJsonApi(arg)
        }
      },
      async 'get /customer_orders'(req, res, next) {
        const db = await getDb()
        next()
        res.mm.resHandleJsonApi = (arg) => {
          const newData = arg.data.map((item) => {
            // 查询 store 详情
            item.store = db.chain
              .get(`store`)
              .find({ id: item.storeId })
              .value()
            // 查询 状态 详情
            item.status_text = {
              1: `已下单`,
              2: `制作中`,
              3: `配送中`,
              4: `已完成`,
            }[item.status]
            return item
          })
          arg.data = newData.reverse()
          return arg.resHandleJsonApi(arg)
        }
      },
      async 'post /api/login/member'(req, res, next) {
        const { mobilePhone, token } = req.body
        const db = await getDb()
        const findUser = db.chain.get(`member`).find({ mobilePhone }).value()
        if (findUser) {
          res.json(findUser)
        } else {
          res.status(403).json({ msg: `用户名或密码错误` })
        }
      },
      async 'post /file/upload'(req, res, next) {
        const multiparty = await util.toolObj.generate.initPackge(`multiparty`)
        const form = new multiparty.Form({
          uploadDir: global.cfg.__uploadDir,
        })
        form.parse(req, async (err, fields = [], files) => {
          const path = require(`path`)
          const file = files.file[0]
          let url = `${global.cfg.__home}/upload/${path.parse(file.path).base}`
          res.json({ data: { url } })
        })
      },
      async 'get /api/goodClassByAll'(req, res, next) {
        const db = await getDb()
        const data = db.data.goodClass.map((item) => {
          // 获取商品
          item.goods_list = db.data.goods_list
            .filter((good) => good.goodClassId === item.id)
            // 获取商品规格
            .map((item) => {
              item.property = db.data.property
                .filter((prop) => (item.property || []).includes(prop.id))
                // 获取规格明细
                .map((item) => {
                  item.values = db.data.propertyValues.filter((obj) => {
                    return (item.propertyValues || []).includes(obj.id)
                  })
                  return item
                })
              return item
            })
          return item
        })
        res.json(wrapApiData({ data }))
      },
      'get /api/pointsFlow': wrapApiData({ data: pointsFlow }),
      'get /api/packages': wrapApiData({ data: packages }),
      'get /api/store': wrapApiData({ data: store }),
      'get /api/goods': wrapApiData({ data: goods }),
      'get /api/levelBenefits': wrapApiData({ data: levelBenefits }),
      'get /api/member': wrapApiData({ data: member }),
      'get /api/rechargeCards': wrapApiData({ data: rechargeCards }),
      'get /api/addresses': wrapApiData({ data: addresses }),
      'get /api/attendance': wrapApiData({ data: attendance }),
      'get /api/customPoints': wrapApiData({ data: customPoints }),
      'get /api/pointsMall': wrapApiData({ data: pointsMall }),
      'get /api/attendanceList': wrapApiData({ data: attendanceList }),
      'get /api/todayAttendance': wrapApiData({ data: todayAttendance }),
      'get /api/orders': wrapApiData({ data: orders }),
      'get /api/customerCoupons': wrapApiData({ data: customerCoupons }),
      'get /api/giftCards': wrapApiData({ data: giftCards }),

      // 创建接口并使用 mockjs 生成数据
      'get /api/test': wrapApiData(
        mockjs.mock({
          'data|3-7': [
            {
              userId: `@id`,
              userName: `@cname`,
            },
          ],
        })
      ),
    },
    db: util.libObj.mockjs.mock({
      // 消费者订单列表
      'customer_orders|5-9': [
        {
          'id|+1': 1,
          // 支持方式
          pay_mode: `微信支付`,
          // 商品数量
          goods_num: `@pick(1,2,3)`,
          created_at: () => {
            return Number(mockjs.mock(`@datetime(T)`)) / 1000
          },
          // 发票状态 1 已开发票 0 未开发票
          invoice_status: `@pick(0,1)`,
          // 订单状态
          // status_text: `已完成`,
          // 备注
          remark: `@ctitle`,
          // 手机号
          mobile: `@phone`,
          // 商家
          'storeId|1-3': 1,
          store: {},
          // 订单状态 1 已下单 2 制作中 3 配送中 4 已完成
          'status|1-4': 1,
          // 完成时间
          completed_time() {
            return this.status === 4 ? mockjs.mock(`@datetime`) : undefined
          },
          // 实付金额
          amount: `@int(1,9999).@int(1,99)`,
          // 完成制作时间
          productioned_time() {
            return this.status === 4 ? mockjs.mock(`@datetime`) : undefined
          },
          // 取单号
          sort_num: `@int(1,9999)`,
          // 订单号
          order_no: () => {
            return Number(mockjs.mock(`@datetime(T)`)) + mockjs.mock(/\d\d\d\d/)
          },
          // 取餐方式 1 堂食 2 外卖
          typeCate: `@pick(1,2)`,
          // 订单商品, 从 goodsPay 查询
          goods: [],
        },
      ],
      // 商店
      store: mockjs.mock({
        'pre|5-9': [
          {
            'id|+1': 1,
            address: `@ctitle`,
            mobile: `@phone`,
            name: `@ctitle`,
          },
        ],
        data() {
          this.pre[0].name = `卓悦中心ONE AVENUE店`
          this.pre[0].address = `深圳市福田区海田路与福华一路交汇深圳天元5栋1层N136`
          this.pre[0].mobile = `14701240124`
          return this.pre
        },
      }).data,
      // 系统用户
      'user|5-9': [
        {
          'id|+1': 1,
          // 登录账号
          user: `@word`,
          // 登录密码
          pass: `@word`,
        },
      ],
      // 顾客
      member: mockjs.mock({
        'pre|5-9': [
          {
            'id|+1': 1,
            // 头像
            avatar: `@image`,
            // 会员等级
            memberLevel: `@pick(1,2,3,4,5)`,
            // 昵称
            nickname: `@ctitle`,
            // 当前成长值
            currentValue: `@int(1,999)`,
            // 手机号码
            mobilePhone: `@phone`,
            // 下一级所需要
            needValue: `@int(1,999)`,
            // 优惠券数量
            couponNum: /\d/,
            // 积分数量
            pointNum: `@int(1,999)`,
            // 余额
            balance: `@int(1,999)`,
            // 礼品卡数量
            giftBalance: /\d/,
            // 入会时间
            openingCardDate: `@datetime`,
            // 性别 1 先生 2 女士
            gender: `@pick(1,2)`,
            // 生日
            birthday: `@datetime(yyyy-MM-dd)`,
          },
        ],
        data() {
          this.pre[0].nickname = `张小白`
          this.pre[0].mobilePhone = `15212341234`
          return this.pre
        },
      }).data,
      // 商品订单记录
      'goodsPay|5-9': [
        {
          'id|+1': 1,
          // 商品 id
          'goodsId|1-3': 1,
          // 订单 id
          'customer_ordersId|1-3': 1,
          // 数量
          'number|1-3': 1,
        },
      ],
      // 规格明细
      'propertyValues|5-9': [
        {
          'id|+1': 1,
          // 默认选中
          is_default: `@pick(0, 1)`,
          // 属性编号
          // code: `Z5DD789B45391F4495`,
          // 属性值
          value: `@ctitle`,
        },
      ],
      //  规格分类
      'property|5-9': [
        {
          'id|+1': 1,
          // 属性名称
          name: `@ctitle`,
          // 属性描述
          desc: `@ctitle`,
          // 明细
          propertyValues: () => [mockjs.mock(`@pick(1,2,3)`)],
        },
      ],
      // 商品列表
      'goods_list|5-9': [
        {
          'id|+1': 1,
          // 所属分类
          'goodClassId|1-3': 1,

          // 规格
          property: () => [mockjs.mock(`@pick(1,2,3)`)],
          // 是否允许用户选择规格
          'use_property|0-1': 0,
          price: `@int(1,999)`,
          content: `@ctitle @ctitle`,
          name: `@ctitle`,
          images: `@image`,
        },
      ],
      // 分类列表
      'goodClass|5-9': [
        {
          'id|+1': 1,
          // 分类图标
          icon: `@image`,
          // 分类名称
          name: `@ctitle`,
        },
      ],
    }),
    // route: {
    //   '/db/*': `/$1`,
    // },
  }
}

async function getDb() {
  const { LowSync, JSONFileSync } = await import(`lowdb`)
  class LowWithLodash extends LowSync {
    chain = lodash.chain(this).get(`data`)
  }
  const adapter = new JSONFileSync(global.cfg.dbJsonPath)
  const db = new LowWithLodash(adapter)
  await db.read()
  return db
}
